package co.gov.medellin.ssti.sub.model.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import co.gov.medellin.ssti.sub.model.dao.ISubprogramaSedeDAO;
import co.gov.medellin.ssti.sub.model.dao.exception.DAOException;
import co.gov.medellin.ssti.sub.model.vo.SubprogramaSedeVO;

public class SubprogramaSedeDAOImpl extends BaseDAOImpl implements
		ISubprogramaSedeDAO {

	public SubprogramaSedeDAOImpl(Connection con) {
		super(con);
	}

	public Collection<SubprogramaSedeVO> findSubprogramaSedeByCriteria(
			SubprogramaSedeVO criteria) throws DAOException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		List<Object> parameters = new ArrayList<Object>();
		StringBuffer query = new StringBuffer(
				"SELECT SUBSEDE.CODIGO CODE, TO_CHAR(SUBSEDE.DESDE,'DD/MM/YYYY') DESDE, "
						+ " TO_CHAR(SUBSEDE.HASTA,'DD/MM/YYYY') HASTA, "
						+ " SUBSEDE.NUMERO_BENEFICIO, SUBSEDE.NUMERO_BEN_DISPONIBLE, "
						+ " SEDE.CODIGO CODESEDE, SEDE.NOMBRE NOMBRESEDE, "
						+ " SUBPRO.CODIGO CODESUBPROGRAMA, SUBPRO.NOMBRE NOMBRESUBPROGRAMA, "
						+ " PRO.CODIGO CODEPROGRAMA, PRO.NOMBRE NOMBREPROGRAMA "
						+ " FROM TCS_BEN_SUBPROGRAMA_SEDE SUBSEDE, "
						+ " TCS_BEN_SEDE SEDE, "
						+ " TCS_BEN_SUBPROGRAMA SUBPRO, "
						+ " TCS_BEN_PROGRAMA PRO "
						+ " WHERE SEDE.CODIGO = SUBSEDE.SEDE_CODIGO "
						+ " AND SUBPRO.CODIGO = SUBSEDE.SBPR_CODIGO "
						+ " AND SUBPRO.PRG_CODIGO =  PRO.CODIGO ");

		if ((Object) criteria.getCodeSede() != null) {
			query.append(" AND SEDE.CODIGO = ? ");
			parameters.add(criteria.getCodeSede());
		}
		if ((Object) criteria.getCodeSubprograma() != null) {
			query.append(" AND SUBPRO.CODIGO = ? ");
			parameters.add(criteria.getCodeSubprograma());
		}
		if ((Object) criteria.getCodePrograma() != null) {
			query.append(" AND PRO.CODIGO = ? ");
			parameters.add(criteria.getCodePrograma());
		}
		query.append(" ORDER BY PRO.NOMBRE,SUBPRO.NOMBRE,DESDE DESC, SEDE.NOMBRE ");

		ArrayList<SubprogramaSedeVO> lsubsede = new ArrayList<SubprogramaSedeVO>();
		try {
			pstmt = conn.prepareStatement(query.toString());
			pstmt = setQueryParameters(pstmt, parameters);
			rst = pstmt.executeQuery();

			SubprogramaSedeVO subsedeVO = null;
			while (rst.next()) {
				subsedeVO = new SubprogramaSedeVO();
				subsedeVO.setCode(new Long(rst.getLong("CODE")));
				subsedeVO.setCodeSede(new Long(rst.getLong("CODESEDE")));
				subsedeVO.setNombreSede(rst.getString("NOMBRESEDE"));
				subsedeVO
						.setCodePrograma(new Long(rst.getLong("CODEPROGRAMA")));
				subsedeVO.setNombrePrograma(rst.getString("NOMBREPROGRAMA"));
				subsedeVO.setCodeSubprograma(new Long(rst
						.getLong("CODESUBPROGRAMA")));
				subsedeVO.setNombreSubprograma(rst
						.getString("NOMBRESUBPROGRAMA"));
				subsedeVO.setDesde(rst.getString("DESDE"));
				subsedeVO.setHasta(rst.getString("HASTA"));
				subsedeVO.setCantidadTotal(rst.getString("NUMERO_BENEFICIO"));
				subsedeVO.setCantidadDisponible(rst
						.getString("NUMERO_BEN_DISPONIBLE"));
				lsubsede.add(subsedeVO);
				subsedeVO = null;
			}
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(rst, pstmt);
		}
		return lsubsede;
	}

	public Collection<SubprogramaSedeVO> findSubprogramaSedeByCode(
			Long codeSubprogramaSede) throws DAOException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String query = "SELECT SUBSEDE.CODIGO CODE, TO_CHAR(SUBSEDE.DESDE,'DD/MM/YYYY') DESDE, "
				+ " TO_CHAR(SUBSEDE.HASTA,'DD/MM/YYYY') HASTA, "
				+ " SUBSEDE.NUMERO_BENEFICIO, SUBSEDE.NUMERO_BEN_DISPONIBLE, "
				+ " SEDE.CODIGO CODESEDE, SEDE.NOMBRE NOMBRESEDE, "
				+ " SUBPRO.CODIGO CODESUBPROGRAMA, SUBPRO.NOMBRE NOMBRESUBPROGRAMA, "
				+ " PRO.CODIGO CODEPROGRAMA, PRO.NOMBRE NOMBREPROGRAMA "
				+ " FROM TCS_BEN_SUBPROGRAMA_SEDE SUBSEDE, "
				+ " TCS_BEN_SEDE SEDE, "
				+ " TCS_BEN_SUBPROGRAMA SUBPRO, "
				+ " TCS_BEN_PROGRAMA PRO "
				+ " WHERE SEDE.CODIGO = SUBSEDE.SEDE_CODIGO "
				+ " AND SUBPRO.CODIGO = SUBSEDE.SBPR_CODIGO "
				+ " AND SUBPRO.PRG_CODIGO =  PRO.CODIGO "
				+ " AND SUBSEDE.CODIGO = ? ";

		query += " ORDER BY PRO.NOMBRE,SUBPRO.NOMBRE,DESDE DESC, SEDE.NOMBRE ";

		ArrayList<SubprogramaSedeVO> lsubsede = new ArrayList<SubprogramaSedeVO>();
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setLong(1, codeSubprogramaSede.longValue());
			rst = pstmt.executeQuery();

			SubprogramaSedeVO subsedeVO = null;
			while (rst.next()) {
				subsedeVO = new SubprogramaSedeVO();
				subsedeVO.setCode(new Long(rst.getLong("CODE")));
				subsedeVO.setCodeSede(new Long(rst.getLong("CODESEDE")));
				subsedeVO.setNombreSede(rst.getString("NOMBRESEDE"));
				subsedeVO
						.setCodePrograma(new Long(rst.getLong("CODEPROGRAMA")));
				subsedeVO.setNombrePrograma(rst.getString("NOMBREPROGRAMA"));
				subsedeVO.setCodeSubprograma(new Long(rst
						.getLong("CODESUBPROGRAMA")));
				subsedeVO.setNombreSubprograma(rst
						.getString("NOMBRESUBPROGRAMA"));
				subsedeVO.setDesde(rst.getString("DESDE"));
				subsedeVO.setHasta(rst.getString("HASTA"));
				subsedeVO.setCantidadTotal(rst.getString("NUMERO_BENEFICIO"));
				subsedeVO.setCantidadDisponible(rst
						.getString("NUMERO_BEN_DISPONIBLE"));
				lsubsede.add(subsedeVO);
				subsedeVO = null;
			}
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(rst, pstmt);
		}
		return lsubsede;
	}

	public void insertUsuarioSede(Long codeSubprogramaSede, Long codeUser,
			String[] param) throws DAOException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String query = "SELECT codigo FROM TCS_BEN_USUARIO_SEDE "
				+ " WHERE usu_codigo = ? AND spse_codigo = ? ";

		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setLong(1, codeUser.longValue());
			pstmt.setLong(2, codeSubprogramaSede.longValue());
			rst = pstmt.executeQuery();
			if (rst.next()) {
				return;
			}
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(rst, pstmt);
		}

		query = "INSERT INTO TCS_BEN_USUARIO_SEDE "
				+ " (CODIGO, USU_CODIGO, SPSE_CODIGO, "
				+ " usuario_crea, fecha_crea, terminal_crea, usuario_modifica, fecha_modifica, terminal_modifica) "
				+ " VALUES (SCS_BEN_USE.nextval, ?, ?, ?, TO_DATE(?,'dd/mm/yyyy'), ?, ?,TO_DATE(?,'dd/mm/yyyy'), ?)";
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setLong(1, codeUser.longValue());
			pstmt.setLong(2, codeSubprogramaSede.longValue());
			pstmt.setString(3, param[0]); // user.getName()
			pstmt.setString(4, param[1]); // dateFormat.format(c.getTime())
			pstmt.setString(5, param[2]); // strTerminal
			pstmt.setString(6, param[3]); // user.getName()
			pstmt.setString(7, param[4]); // dateFormat.format(c.getTime())
			pstmt.setString(8, param[5]); // strTerminal
			int iRegInsert = pstmt.executeUpdate();
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(pstmt);
		}

	}

	public String[] insertSubprogramaSede(Long codeSede, Long codeSubprograma,
			String desde, String hasta, String cantidad, String[] param)
			throws DAOException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String retorno[] = new String[2];
		retorno[0] = "false";
		try {
			int validate1 = validateExist(codeSede, codeSubprograma, desde,
					hasta);

			if (validate1 == 0) {
				String usuarioCrea = param[0];
				String fechaCrea = param[1];
				String terminalCrea = param[2];
				String usuarioModifica = param[3];
				String fechaModifica = param[4];
				String terminalModifica = param[5];
				int iCantidad = new Integer(cantidad).intValue();
				if (validateExist(codeSede, codeSubprograma)) {
					String validate[] = validateDates(codeSede,
							codeSubprograma, desde);
					if (validate[0].equals("true")) {
						// {user.getName(),
						// dateFormat.format(c.getTime()),strTerminal,user.getName(),
						// dateFormat.format(c.getTime()),strTerminal};
						String query = "INSERT INTO TCS_BEN_SUBPROGRAMA_SEDE "
								+ " (CODIGO, SEDE_CODIGO, SBPR_CODIGO, "
								+ " DESDE, HASTA, NUMERO_BENEFICIO, "
								+ " NUMERO_BEN_DISPONIBLE, "
								+ " usuario_crea, fecha_crea, terminal_crea, usuario_modifica, fecha_modifica, terminal_modifica) "
								+ " VALUES (SCS_BEN_SPSE.nextval, ?, ?,"
								+ " TO_DATE(?,'dd/mm/yyyy'), TO_DATE(?,'dd/mm/yyyy'), ?, ?, ?, TO_DATE(?,'dd/mm/yyyy'), ?, ?, TO_DATE(?,'dd/mm/yyyy'), ?)";
						int countInsert = 0;
						try {
							pstmt = conn.prepareStatement(query);
							pstmt.setLong(1, codeSede.longValue());
							pstmt.setLong(2, codeSubprograma.longValue());
							pstmt.setString(3, desde);
							pstmt.setString(4, hasta);
							pstmt.setInt(5, iCantidad);
							pstmt.setInt(6, iCantidad);
							pstmt.setString(7, usuarioCrea);
							pstmt.setString(8, fechaCrea);
							pstmt.setString(9, terminalCrea);
							pstmt.setString(10, usuarioModifica);
							pstmt.setString(11, fechaModifica);
							pstmt.setString(12, terminalModifica);

							countInsert = pstmt.executeUpdate();
						} catch (SQLException e) {
							throw new DAOException(e);
						} finally {
							close(pstmt);
						}
						if (countInsert > 0) {
							retorno[0] = "true";
							query = "SELECT MAX(codigo) codigo FROM TCS_BEN_SUBPROGRAMA_SEDE";
							try {
								pstmt = conn.prepareStatement(query);
								rst = pstmt.executeQuery();
								if (rst.next()) {
									retorno[1] = rst.getString("codigo");
								} else {
									retorno[0] = "false";
								}
							} catch (SQLException e) {
								throw new DAOException(e);
							} finally {
								close(rst, pstmt);
							}
						}
					} else {
						if ((Object) validate[1] != null) {
							// indica que solo se debe insertar
							retorno[0] = "ususede";
							retorno[1] = validate[1];
						} else {
							retorno[1] = "Ese beneficio ya esta cubierto en ese periodo de tiempo, seleccione otro rango!";
						}
					}
				} else {// esto es duplicado.. luego lo reviso mejor.
					String query = "INSERT INTO TCS_BEN_SUBPROGRAMA_SEDE "
							+ " (CODIGO, SEDE_CODIGO, SBPR_CODIGO, "
							+ " DESDE, HASTA, NUMERO_BENEFICIO, "
							+ " NUMERO_BEN_DISPONIBLE, "
							+ " usuario_crea, fecha_crea, terminal_crea, usuario_modifica, fecha_modifica, terminal_modifica) "
							+ " VALUES (SCS_BEN_SPSE.nextval, ?, ?,"
							+ " TO_DATE(?,'dd/mm/yyyy'), TO_DATE(?,'dd/mm/yyyy'), ?, ?, ?, TO_DATE(?,'dd/mm/yyyy'), ?, ?, TO_DATE(?,'dd/mm/yyyy'), ?)";
					int countInsert = 0;
					try {
						pstmt = conn.prepareStatement(query);
						pstmt.setLong(1, codeSede.longValue());
						pstmt.setLong(2, codeSubprograma.longValue());
						pstmt.setString(3, desde);
						pstmt.setString(4, hasta);
						pstmt.setInt(5, iCantidad);
						pstmt.setInt(6, iCantidad);
						pstmt.setString(7, usuarioCrea);
						pstmt.setString(8, fechaCrea);
						pstmt.setString(9, terminalCrea);
						pstmt.setString(10, usuarioModifica);
						pstmt.setString(11, fechaModifica);
						pstmt.setString(12, terminalModifica);
						countInsert = pstmt.executeUpdate();
					} catch (SQLException e) {
						throw new DAOException(e);
					} finally {
						close(pstmt);
					}
					if (countInsert > 0) {
						retorno[0] = "true";
						query = "SELECT MAX(codigo) codigo FROM TCS_BEN_SUBPROGRAMA_SEDE";
						try {
							pstmt = conn.prepareStatement(query);
							rst = pstmt.executeQuery();
							if (rst.next()) {
								retorno[1] = rst.getString("codigo");
							} else {
								retorno[0] = "false";
							}
						} catch (SQLException e) {
							throw new DAOException(e);
						} finally {
							close(rst, pstmt);
						}
					} else {
						retorno[0] = "false";
					}
				}
			} else {
				// "La sede seleccionada ya tiene asignado ese beneficio en el mismo periodo de tiempo";
				retorno[0] = "ususede";
				retorno[1] = validate1 + "";
			}

			return retorno;
		} catch (SQLException e) {
			throw new DAOException(e);
		}
	}

	public boolean actualizarSubproSede(Long codeSubprogramaSede,
			String[] parArr) throws DAOException {
		// {strCodeSede,desde,hasta,cantidad,cantidad,user.getName(),dateFormat.format(c.getTime()),strTerminal};
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String query = "UPDATE TCS_BEN_SUBPROGRAMA_SEDE SET "
				+ " SEDE_CODIGO = ?, DESDE = TO_DATE(?,'dd/mm/yyyy'), "
				+ " HASTA = TO_DATE(?,'dd/mm/yyyy'), "
				+ " NUMERO_BENEFICIO = NUMERO_BENEFICIO + ?, "
				+ " NUMERO_BEN_DISPONIBLE = NUMERO_BEN_DISPONIBLE + ?, "
				+ " usuario_modifica = ?, "
				+ " fecha_modifica = TO_DATE(?,'dd/mm/yyyy'), "
				+ " terminal_modifica = ? WHERE CODIGO = ?";// + code;
		// {strCodeSede,desde,hasta,cantidad,cantidad,user.getName(),dateFormat.format(c.getTime()),strTerminal};
		Long codeSede = new Long(parArr[0]); // strCodeSede
		String desde = parArr[1];// desde
		String hasta = parArr[2];
		Integer cantidad = new Integer(parArr[3]);
		String usuario = parArr[5];		
		String fechaModifica = parArr[6];		
		String terminal = parArr[7];
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setLong(1, codeSede.longValue());
			pstmt.setString(2, desde);
			pstmt.setString(3, hasta);
			pstmt.setInt(4, cantidad.intValue());
			pstmt.setInt(5, cantidad.intValue());
			pstmt.setString(6, usuario);
			pstmt.setString(7, fechaModifica);
			pstmt.setString(8, terminal);
			pstmt.setLong(9, codeSubprogramaSede.longValue());

			return (pstmt.executeUpdate() > 0) ? true : false;
		} catch (SQLException e) {
			throw new DAOException(e);
		} finally {
			close(rst, pstmt);
		}
	}

	private int validateExist(Long codeSede, Long codeSubprograma,
			String desde, String hasta) throws SQLException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String query = "SELECT codigo FROM TCS_BEN_SUBPROGRAMA_SEDE "
				+ " WHERE sede_codigo = ? AND sbpr_codigo = ? "
				+ " AND desde = TO_DATE(?,'dd/mm/yyyy')"
				+ " AND hasta = TO_DATE(?,'dd/mm/yyyy')";
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setLong(1, codeSede.longValue());
			pstmt.setLong(2, codeSubprograma.longValue());
			pstmt.setString(3, desde);
			pstmt.setString(4, hasta);
			rst = pstmt.executeQuery();
			if (rst.next()) {
				return rst.getInt("codigo");
			} else {
				return 0;
			}
		} finally {
			close(rst, pstmt);
		}
	}

	private boolean validateExist(Long codeSede, Long codeSubprograma)
			throws SQLException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String query = "SELECT codigo FROM TCS_BEN_SUBPROGRAMA_SEDE "
				+ " WHERE sede_codigo = ? AND sbpr_codigo = ?";

		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setLong(1, codeSede.longValue());
			pstmt.setLong(2, codeSubprograma.longValue());
			rst = pstmt.executeQuery();

			return rst.next() ? true : false;
		} finally {
			close(rst, pstmt);
		}
	}

	private String[] validateDates(Long codeSede, Long codeSubprograma,
			String desde) throws SQLException {
		PreparedStatement pstmt = null;
		ResultSet rst = null;

		String query = "SELECT case WHEN hasta < TO_DATE(?,'dd/mm/yyyy') THEN 'true' "
				+ " ELSE 'false' "
				+ " END validacion, codigo "
				+ " FROM tcs_ben_subprograma_sede "
				+ " WHERE codigo =  (SELECT MAX(codigo) FROM tcs_ben_subprograma_sede "
				+ " WHERE sbpr_codigo = ? " + " AND sede_codigo = ? )";
		String retorno[] = new String[2];
		try {
			pstmt = conn.prepareStatement(query);
			pstmt.setString(1, desde);
			pstmt.setLong(2, codeSubprograma.longValue());
			pstmt.setLong(3, codeSede.longValue());
			rst = pstmt.executeQuery();

			if (rst.next()) {
				String test = rst.getString("validacion");
				retorno[0] = test;
				retorno[1] = rst.getString("codigo");
			} else {
				retorno[0] = "false";
			}
		} finally {
			close(rst, pstmt);
		}
		return retorno;
	}
}
